package com.xrui.hbaseview.ui.forms;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;

import com.xrui.hbaseview.data.ColumnFamily;
import com.xrui.hbaseview.data.TableDescriptor;
import com.xrui.hbaseview.ui.design.JCellEditor;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Map;

public class TableMetadataDialog extends JDialog {

    //region Variables
    private static final long serialVersionUID = -2969175353751989403L;

    private JPanel contentPane;
    private JButton buttonCancel;
    private JTable tableMetadata;
    private DefaultTableModel tableModel;
    private JComboBox cmbFamilies;
    private DefaultComboBoxModel cmbFamiliesModel;
    private JTable columnMetadata;
    private DefaultTableModel columnModel;
    private boolean okPressed;

    //region Constructor
    @SuppressWarnings("unchecked")
    public TableMetadataDialog(final TableDescriptor descriptor) {
        setContentPane(contentPane);
        setModal(true);
        setTitle(descriptor.getName() + " table metadata");
        getRootPane().setDefaultButton(buttonCancel);

        this.tableModel = new DefaultTableModel();
        this.tableMetadata.setModel(this.tableModel);

        this.tableModel.addColumn("Key");
        this.tableModel.addColumn("Value");
        this.tableMetadata.setRowHeight(this.tableMetadata.getFont().getSize() + 8);
        this.tableMetadata.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);

        this.tableMetadata.getColumn("Key").setCellEditor(new JCellEditor(null, false));
        this.tableMetadata.getColumn("Value").setCellEditor(new JCellEditor(null, false));

        for (Map.Entry<String, String> entry : descriptor.getMetadata().entrySet()) {
            this.tableModel.addRow(new Object[]{entry.getKey(), entry.getValue()});
        }

        this.columnModel = new DefaultTableModel();
        this.columnMetadata.setModel(this.columnModel);

        this.columnModel.addColumn("Key");
        this.columnModel.addColumn("Value");
        this.columnMetadata.setRowHeight(this.columnMetadata.getFont().getSize() + 8);
        this.columnMetadata.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);

        this.columnMetadata.getColumn("Key").setCellEditor(new JCellEditor(null, false));
        this.columnMetadata.getColumn("Value").setCellEditor(new JCellEditor(null, false));

        this.cmbFamiliesModel = new DefaultComboBoxModel();
        this.cmbFamilies.setModel(this.cmbFamiliesModel);

        this.cmbFamilies.getEditor().addActionListener(
            e -> {
                Object item = cmbFamilies.getEditor().getItem();
                if (item == null || item instanceof String && ((String) item).isEmpty()) {
                    Object selectedItem = cmbFamilies.getSelectedItem();
                    if (selectedItem != null) {
                        cmbFamilies.removeItem(selectedItem);
                    }
                } else if (item instanceof String) {
                    ColumnFamily columnFamily = new ColumnFamily((String) item);

                    int index = cmbFamiliesModel.getIndexOf(columnFamily);
                    if (index == -1) {
                        cmbFamilies.addItem(columnFamily);
                    } else {
                        columnFamily = (ColumnFamily) cmbFamiliesModel.getElementAt(index);
                    }

                    cmbFamilies.setSelectedItem(columnFamily);
                }
            });

        this.cmbFamilies.addActionListener(
            e -> {
                columnModel.setRowCount(0);

                Object item = cmbFamilies.getSelectedItem();
                if (item instanceof ColumnFamily) {
                    ColumnFamily columnFamily = (ColumnFamily) item;

                    for (Map.Entry<String, String> entry : columnFamily.getMetadata().entrySet()) {
                        columnModel.addRow(new Object[]{entry.getKey(), entry.getValue()});
                    }
                }
            });

        for (ColumnFamily columnFamily : descriptor.families()) {
            this.cmbFamilies.addItem(columnFamily);
        }

        if (this.cmbFamilies.getItemCount() > 0) {
            this.cmbFamilies.setSelectedIndex(0);
        }

        buttonCancel.addActionListener(
            e -> onCancel());

        // call onCancel() when cross is clicked
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(
            new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    onCancel();
                }
            });

        // call onCancel() on ESCAPE
        contentPane.registerKeyboardAction(
            e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    }
    //endregion

    //region Public Methods
    public boolean showDialog(Component owner) {
        this.setComponentOrientation(owner.getComponentOrientation());
        this.pack();
        this.setResizable(false);
        this.setLocationRelativeTo(owner);
        this.setVisible(true);

        return this.okPressed;
    }

    private void onCancel() {
        // add your code here if necessary
        dispose();
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        contentPane = new JPanel();
        contentPane.setLayout(new GridLayoutManager(3, 1, new Insets(10, 10, 10, 10), -1, -1));
        contentPane.setMaximumSize(new Dimension(-1, -1));
        contentPane.setMinimumSize(new Dimension(-1, -1));
        contentPane.setPreferredSize(new Dimension(400, 400));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel1, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, 1, null, null, null, 0, false));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        panel1.add(panel2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_VERTICAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        buttonCancel = new JButton();
        buttonCancel.setText("Cancel");
        panel2.add(buttonCancel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new GridLayoutManager(3, 2, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel3, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        final JLabel label1 = new JLabel();
        label1.setText("Table metadata");
        panel3.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JScrollPane scrollPane1 = new JScrollPane();
        panel3.add(scrollPane1, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        tableMetadata = new JTable();
        scrollPane1.setViewportView(tableMetadata);
        final JLabel label2 = new JLabel();
        label2.setText("Column Family");
        panel3.add(label2, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JToolBar toolBar1 = new JToolBar();
        toolBar1.setFloatable(false);
        panel3.add(toolBar1, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 20), null, 0, false));
        cmbFamilies = new JComboBox();
        cmbFamilies.setEditable(false);
        toolBar1.add(cmbFamilies);
        final JToolBar.Separator toolBar$Separator1 = new JToolBar.Separator();
        toolBar1.add(toolBar$Separator1);
        final JToolBar toolBar2 = new JToolBar();
        toolBar2.setFloatable(false);
        panel3.add(toolBar2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 20), null, 0, false));
        final JScrollPane scrollPane2 = new JScrollPane();
        contentPane.add(scrollPane2, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        columnMetadata = new JTable();
        scrollPane2.setViewportView(columnMetadata);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return contentPane;
    }
}
